package com.minimalist.lindi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Assert;
import cn.hutool.http.HttpStatus;
import com.minimalist.common.config.exception.BusinessException;
import com.minimalist.common.config.mybatis.bo.PageResp;
import com.minimalist.common.entity.basic.enums.RespEnum;
import com.minimalist.common.entity.basic.vo.file.FileUploadRespVO;
import com.minimalist.common.entity.basic.vo.file.FileVO;
import com.minimalist.common.entity.lindi.po.LindiTradeApplicationTemplateConfirmLetter;
import com.minimalist.common.entity.lindi.vo.contracttemplate.LindiContractTemplateVO;
import com.minimalist.common.entity.lindi.vo.tradeapplicationtemplateconfirmletter.LindiTradeApplicationTemplateConfirmLetterQueryVO;
import com.minimalist.common.entity.lindi.vo.tradeapplicationtemplateconfirmletter.LindiTradeApplicationTemplateConfirmLetterVO;
import com.minimalist.common.feign.client.basic.FileFeignClient;
import com.minimalist.common.response.R;
import com.minimalist.common.utils.UnqIdUtil;
import com.minimalist.lindi.manager.ContractTemplateManager;
import com.minimalist.lindi.mapper.LindiTradeApplicationTemplateConfirmLetterMapper;
import com.minimalist.lindi.service.LindiTradeApplicationTemplateConfirmLetterService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 林地指标交易平台_交易申请确认函模板文件 服务层实现。
 *
 * @author 11987
 * @since 2025-06-06
 */
@Service
public class LindiTradeApplicationTemplateConfirmLetterServiceImpl extends ServiceImpl<LindiTradeApplicationTemplateConfirmLetterMapper, LindiTradeApplicationTemplateConfirmLetter> implements LindiTradeApplicationTemplateConfirmLetterService{

    private static final Logger logger = LoggerFactory.getLogger(LindiTradeApplicationTemplateConfirmLetterServiceImpl.class);

    @Autowired
    private LindiTradeApplicationTemplateConfirmLetterMapper mapper;

    @Autowired
    private FileFeignClient fileFeignClient;

    @Autowired
    private ContractTemplateManager contractTemplateManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTradeApplicationTemplateConfirmLetter(LindiTradeApplicationTemplateConfirmLetterVO tradeApplicationTemplateConfirmLetterVO){
        LindiTradeApplicationTemplateConfirmLetter record = BeanUtil.copyProperties(tradeApplicationTemplateConfirmLetterVO,
                LindiTradeApplicationTemplateConfirmLetter.class);
        record.setTemplateConfirmLetterId(UnqIdUtil.uniqueId());
        int insert = mapper.insert(record, true);
        Assert.isTrue(insert == 1, () -> new BusinessException("添加交易申请确认函模板失败"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTradeApplicationTemplateConfirmLetterByTradeApplicationTemplateConfirmLetterId(
            Long tradeApplicationTemplateConfirmLetterId){
        LindiTradeApplicationTemplateConfirmLetter record = mapper
                .selectTradeApplicationTemplateConfirmLetterByTradeApplicationTemplateConfirmLetterId
                        (tradeApplicationTemplateConfirmLetterId);
        Assert.notNull(record, () -> new BusinessException("交易申请确认函模板不存在"));
        List<Long> fileIds = new ArrayList<>();
        if (record.getFileId() != null){
            fileIds.add(record.getFileId());
        }
        if (!fileIds.isEmpty()){
            try{
                R<Void> result = fileFeignClient.deleteBatchFiles(fileIds);
                if (!Objects.equals(result.getCode(), RespEnum.SUCCESS.getCode())){
                    logger.warn("删除确认函模板文件失败，文件IDs: {}, 错误信息: {}", fileIds, result.getMessage());
                }
            } catch (Exception e){
                logger.warn("删除确认函模板文件异常，文件IDs: {}, 异常信息: {}", fileIds, e.getMessage());
            }
        }
        int delete = mapper.delete(record);
        Assert.isTrue(delete == 1, () -> new BusinessException("删除交易申请确认函模板失败"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTradeApplicationTemplateConfirmLetterByTradeApplicationTemplateConfirmLetterId(
            LindiTradeApplicationTemplateConfirmLetterVO tradeApplicationTemplateConfirmLetterVO){
        LindiTradeApplicationTemplateConfirmLetter record = mapper
                .selectTradeApplicationTemplateConfirmLetterByTradeApplicationTemplateConfirmLetterId(tradeApplicationTemplateConfirmLetterVO
                        .getTemplateConfirmLetterId());
        Assert.notNull(record, () -> new BusinessException("交易申请确认函模板不存在"));
        BeanUtil.copyProperties(tradeApplicationTemplateConfirmLetterVO, record,
                CopyOptions.create().ignoreNullValue());
        int update = mapper.update(record);
        Assert.isTrue(update == 1, () -> new BusinessException("更新交易申请确认函模板失败"));
    }

    @Override
    public PageResp<LindiTradeApplicationTemplateConfirmLetterVO>
    getPageTradeApplicationTemplateConfirmLetterList(
            LindiTradeApplicationTemplateConfirmLetterQueryVO queryVO){
        Page<LindiTradeApplicationTemplateConfirmLetter> page = mapper.selectPageTradeApplicationTemplateConfirmLetterList(queryVO);
        List<LindiTradeApplicationTemplateConfirmLetterVO> voList = BeanUtil.copyToList(page.getRecords(),
                LindiTradeApplicationTemplateConfirmLetterVO.class);

        // 收集所有文件ID
        List<Long> fileIds = page.getRecords().stream().map(
                LindiTradeApplicationTemplateConfirmLetter::getFileId).toList();

        // 批量获取文件信息
        Map<Long, FileVO> fileMap = new HashMap<>(16);

        if (!fileIds.isEmpty()){
            R<List<FileVO>> fileResult = fileFeignClient.getFileListByFileIds(fileIds);
            if (fileResult.getCode() == HttpStatus.HTTP_OK
                    && fileResult.getData() != null){
                fileMap = fileResult.getData().stream()
                        .collect(Collectors.toMap(FileVO::getFileId
                                , Function.identity()));
            }
        }

        // 设置文件信息到VO中
        for (LindiTradeApplicationTemplateConfirmLetterVO vo : voList){
            if (vo.getFileId() != null){
                vo.setFile(fileMap.get(vo.getFileId()));
            }
        }

        return new PageResp<>(voList, voList.size());
    }

    @Override
    public LindiTradeApplicationTemplateConfirmLetterVO getTradeApplicationTemplateConfirmLetterByTradeApplicationTemplateConfirmLetterId(
            Long tradeApplicationTemplateConfirmLetterId){
        LindiTradeApplicationTemplateConfirmLetter record = mapper
                .selectTradeApplicationTemplateConfirmLetterByTradeApplicationTemplateConfirmLetterId(
                        tradeApplicationTemplateConfirmLetterId);
        Assert.notNull(record, () -> new BusinessException("交易申请确认函模板不存在"));
        LindiTradeApplicationTemplateConfirmLetterVO lindiTradeApplicationTemplateConfirmLetterVO
                = BeanUtil.copyProperties(record
                , LindiTradeApplicationTemplateConfirmLetterVO.class);

        if (record.getFileId() != null){
            R<FileVO> fileResult = fileFeignClient
                    .getFileByFileId(record.getFileId());
            if (fileResult.getCode() == HttpStatus.HTTP_OK
                    && fileResult.getData() != null){
                lindiTradeApplicationTemplateConfirmLetterVO.setFile(
                        fileResult.getData());
            }
        }
        return lindiTradeApplicationTemplateConfirmLetterVO;
    }

    @Override
    public void deleteTradeApplicationTemplateConfirmLetterFileByFileId(Long fileId){
        try{
            R<Void> result = fileFeignClient.deleteFile(fileId);
            if (!Objects.equals(result.getCode(), RespEnum.SUCCESS.getCode())){
                logger.warn("删除确认函模板文件失败，文件ID: {}, 错误信息: {}", fileId, result.getMessage());
            }
        } catch (Exception e){
            logger.warn("删除确认函模板文件异常，文件ID: {}, 异常信息: {}", fileId, e.getMessage());
        }
    }

    @Override
    public LindiTradeApplicationTemplateConfirmLetterVO generateTemplateConfirmLetter(
            Long tradeApplicationId
            , Long confirmLetterTemplateId
            , String confirmLetterType, Long createId, Long tenantId){
        R<FileUploadRespVO> fileUploadRespVO = contractTemplateManager.generateContract(
                tradeApplicationId, confirmLetterTemplateId
                , confirmLetterType, createId, tenantId);
        LindiTradeApplicationTemplateConfirmLetterVO tradeApplicationTemplateConfirmLetterVO
                = new LindiTradeApplicationTemplateConfirmLetterVO();
        tradeApplicationTemplateConfirmLetterVO.setTemplateConfirmLetterId(
                UnqIdUtil.uniqueId());
        tradeApplicationTemplateConfirmLetterVO.setTradeApplicationId(tradeApplicationId);
        tradeApplicationTemplateConfirmLetterVO.setConfirmLetterType(confirmLetterType);
        tradeApplicationTemplateConfirmLetterVO.setCreateId(createId);
        tradeApplicationTemplateConfirmLetterVO.setUpdateId(createId);
        LocalDateTime now = LocalDateTime.now();
        tradeApplicationTemplateConfirmLetterVO.setCreateTime(now);
        tradeApplicationTemplateConfirmLetterVO.setUpdateTime(now);
        tradeApplicationTemplateConfirmLetterVO.setFileId(fileUploadRespVO.getData()
                .getFileId());

        LindiTradeApplicationTemplateConfirmLetter lindiTradeApplicationTemplateConfirmLetter
                = BeanUtil.copyProperties(tradeApplicationTemplateConfirmLetterVO
                , LindiTradeApplicationTemplateConfirmLetter.class);
        int insert = mapper.insert(lindiTradeApplicationTemplateConfirmLetter);
        Assert.isTrue(insert == 1, () -> new BusinessException(
                "插入交易申请确认函模板失败"));
        return tradeApplicationTemplateConfirmLetterVO;
    }

    @Override
    public List<LindiContractTemplateVO> getContractTemplateList(){
        return contractTemplateManager.getContractTemplateList();
    }
}
